/**
 * @description
 */


package com.yjx.crm.service;

import com.yjx.crm.base.BaseService;
import com.yjx.crm.dao.ModuleMapper;
import com.yjx.crm.dao.PermissionMapper;
import com.yjx.crm.model.TreeModel;
import com.yjx.crm.utils.AssertUtil;
import com.yjx.crm.vo.Module;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class ModuleService extends BaseService<Module,Integer> {
    @Resource
    private ModuleMapper moduleMapper;

    @Resource
    private PermissionMapper permissionMapper;

    /*查询所有的资源列表*/
    public List<TreeModel> queryAllModules(Integer roleId) {
        //查询所有的资源列表
        List<TreeModel> treeModelList = moduleMapper.queryAllModules();
        //查询指定角色已经授权过的资源列表
        List<Integer> permissionIds = permissionMapper.queryRoleHasModuleIdsByRoleId(roleId);
        //判断角色是否拥有资源ID
        if (permissionIds != null && permissionIds.size() > 0) {
            treeModelList.forEach(treeModel -> {
                if (permissionIds.contains(treeModel.getId())) {
                    treeModel.setChecked(true);
                }
            });

        }
        return treeModelList;
    }

    /*查询资源列表*/
    public Map<String,Object> queryModuleList() {
        Map<String,Object> map = new HashMap<>();
        List<Module> moduleList = moduleMapper.queryModuleList();
        map.put("code",0);
        map.put("msg","");
        map.put("count",moduleList.size());
        map.put("data",moduleList);

        return map;
    }

    /**
     * 1.参数校验
     *     菜单名
     *         非空 同一层级 菜单名唯一
     *     url
     *        二级菜单时 非空 不可重复
     *     上级菜单 parentId
     *        一级菜单  parentId (-1)
     *        二级|三级菜单   parentId 非空 上级菜单记录必须存在
     *     菜单层级  grade
     *       非空  0|1|2
     *     权限码  optValue
     *        非空  不可重复
     * 2.参数默认值设置
     *      isValid   createDate  updateDate
     * 3.执行添加 判断结果
     */

    @Transactional(propagation = Propagation.REQUIRED)
    public void addModule(Module module) {
        /*1.参数校验*/
        //层级    grade
        Integer grade = module.getGrade();
        AssertUtil.isTrue(null == grade || !(grade == 0 || grade == 1 || grade == 2),"菜单层级非法!");

        //模块名称  moduleName
        AssertUtil.isTrue(StringUtils.isBlank(module.getModuleName()),"请输入菜单名!");
        //模块名称  moduleName  同一层级唯一
        AssertUtil.isTrue(null != moduleMapper.queryModuleByGradeAndModuleName(grade,module.getModuleName()),"该层级下模块名称已存在!");

        //如果是二级菜单
        if (grade == 1) {
            //地址 url        二级菜单（grade=1）；非空
            AssertUtil.isTrue(StringUtils.isBlank(module.getUrl()),"URL不能为空!");
            //地址 url        二级菜单 grade=1）   同一层级唯一
            AssertUtil.isTrue(null != moduleMapper.queryModuleByGradeAndUrl(grade,module.getUrl()),"URL不可重复!");
        }

        //父级菜单    parentId  一级
        if (grade == 0) {
            module.setParentId(-1);
        }
        //父级菜单    parentId  二级/三级
        if (grade != 0) {
            //非空
            AssertUtil.isTrue(null == module.getParentId(),"父级菜单不能为空!");
            //父级菜单必须存在（将父级菜单的ID作为主键，查询资源记录）
            AssertUtil.isTrue(null == moduleMapper.selectByPrimaryKey(module.getParentId()),"请指定正确的父菜单!");
        }
        //权限    optValue    非空
        AssertUtil.isTrue(StringUtils.isBlank(module.getOptValue()),"权限码不能为空!");
        //权限码   optValue    不可重复
        AssertUtil.isTrue(null != moduleMapper.queryModuleByOptValue(module.getOptValue()),"权限码已存在!");

        /*2.设置参数的默认值*/
        //是否有效  isValid = 1
        module.setIsValid((byte) 1);
        //创建时间createDate    系统当前时间
        module.setCreateDate(new Date());
        //修改时间updateDate    系统当前时间
        module.setUpdateDate(new Date());

        /*3.执行添加操作，判断受影响的行数*/
        AssertUtil.isTrue(moduleMapper.insertSelective(module) < 1 ,"添加资源失败!");





    }

    /**
     * 1.参数校验
     *    id 记录必须存在
     *     菜单名
     *         非空 同一层级 菜单名唯一
     *     url
     *        二级菜单时 非空 不可重复
     *     上级菜单 parentId
     *        二级|三级菜单   parentId 非空 上级菜单记录必须存在
     *     菜单层级  grade
     *       非空  0|1|2
     *     权限码  optValue
     *        非空  不可重复
     * 2.参数默认值设置
     *      updateDate
     * 3.执行更新 判断结果
     */
    @Transactional(propagation = Propagation.REQUIRED)
    public void updateModule(Module module) {
        /*1.参数校验*/
        //id   非空，数据存在
        //非空判断
        AssertUtil.isTrue(null == module.getId(),"待更新记录不存在!");
        //通过id查询资源对象
        Module temp = moduleMapper.selectByPrimaryKey(module.getId());
        //判断记录是否存在
        AssertUtil.isTrue(null == temp,"待更新记录不存在!");

        //层级    grade
        Integer grade = module.getGrade();
        AssertUtil.isTrue(null == grade || !(grade == 0 || grade == 1 || grade == 2),"菜单层级不合法!");

        //模块名称  moduleName
        AssertUtil.isTrue(StringUtils.isBlank(module.getModuleName()),"模块名称不能为空!");
        //通过层级与模块名称查询资源对象
        temp = moduleMapper.queryModuleByGradeAndModuleName(grade,module.getModuleName());
        if (temp != null) {
            AssertUtil.isTrue(!(temp.getId()).equals(module.getId()),"该层级下菜单名已存在!");
        }

        //地址    url
        if (grade == 1) {
            AssertUtil.isTrue(StringUtils.isBlank(module.getUrl()),"菜单URL不能为空!");
            //通过层级与菜单URL查询资源对象
            temp = moduleMapper.queryModuleByGradeAndUrl(grade,module.getUrl());
            //判断是否存在
            if (temp != null) {
                AssertUtil.isTrue(!(temp.getId()).equals(module.getId()),"该层级下菜单URL已存在!");
            }
        }

        //权限码   optValue
        AssertUtil.isTrue(StringUtils.isBlank(module.getOptValue()),"权限码不能为空!");
        //通过权限码查询资源对象
        temp = moduleMapper.queryModuleByOptValue(module.getOptValue());
        //判断是否为空
        if (temp != null) {
            AssertUtil.isTrue(!(temp.getId()).equals(module.getId()),"权限已存在!");

        }
        /*2.设置参数的默认值*/
        //修改时间
        module.setUpdateDate(new Date());

        /*3.执行更新操作*/
        AssertUtil.isTrue(moduleMapper.updateByPrimaryKeySelective(module) < 1,"修改资源失败!");
    }

    /**
     * 1.记录必须存在
     *     id 非空  记录存在
     * 2.如果待删除的菜单存在子菜单  不允许直接删除当前菜单
     * 3.如果删除的菜单 在权限表中存在对应记录  此时要级联删除权限表对应记录
     */
    @Transactional(propagation = Propagation.REQUIRED)
    public void deleteModule(Integer id) {
        //判断id是否为空
        AssertUtil.isTrue(null == id,"待删除记录不存在!");
        //通过id查询资源对象
        Module temp = moduleMapper.selectByPrimaryKey(id);
        //判断资源对象是否为空
        AssertUtil.isTrue(null == temp,"待删除记录不存在!");

        //如果当前资源存在子记录
        Integer count = moduleMapper.queryModuleByParentId(id);
        //如果存在子记录，不可删除
        AssertUtil.isTrue(count > 0,"该子记录不可删除!");

        //通过资源id查询权限表中是否存在记录
        count = permissionMapper.countPermissionByModuleId(id);
        //判断是否存在，存在则删除
        if (count > 0) {
            //删除指定资源ID的权限记录
            permissionMapper.deletePermissionByModuleId(id);
        }

        //设置无效记录
        temp.setIsValid((byte) 0);
        temp.setUpdateDate(new Date());

        //执行更新
        AssertUtil.isTrue(moduleMapper.updateByPrimaryKeySelective(temp) < 1,"删除资源失败!");

    }

}
